home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / ADVANCED / WARP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.3 KB  |  285 lines

  1.  
  2. /* warp.c - by David Blythe, SGI */
  3.  
  4. /* Image warping operations can be done via OpenGL texture mapping. */
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <GL/glut.h>
  9. #include <math.h>
  10. #include "texture.h"
  11.  
  12. static unsigned *image;
  13. static int width, height, components;
  14. static float incr = .05, dir = 1.0;
  15.  
  16. #define MAXMESH 32
  17.  
  18. float Ml[4 * 2 * (MAXMESH + 1) * 2 * (MAXMESH + 1)];
  19.  
  20. float N = 1.5;
  21. float B = -1.5;
  22.  
  23. void
  24. mesh1(float x0, float x1, float y0, float y1,
  25.   float s0, float s1, float t0, float t1, float z, int nx, int ny)
  26. {
  27.   float y, x, s, t, dx, dy, ds, dt, vb[3], tb[2];
  28.   float v;
  29.   float *mp = Ml;
  30.  
  31.   dx = (x1 - x0) / nx;
  32.   dy = (y1 - y0) / ny;
  33.   ds = (s1 - s0) / nx;
  34.   dt = (t1 - t0) / ny;
  35.   y = y0;
  36.   t = t0;
  37.   vb[2] = z;
  38.   while (y < y1) {
  39.     x = x0;
  40.     s = s0;
  41.     while (x <= x1) {
  42.       tb[0] = s;
  43.       tb[1] = t;
  44.       vb[0] = x;
  45.       vb[1] = y;
  46.       v = N * N - x * x - y * y;
  47.       if (v < 0.0)
  48.         v = 0.0;
  49.       vb[2] = sqrt(v) + B;
  50.       if (vb[2] < 0.)
  51.         vb[2] = 0.0;
  52.       *mp++ = tb[0];
  53.       *mp++ = tb[1];
  54.       mp += 2;
  55.       *mp++ = vb[0];
  56.       *mp++ = vb[1];
  57.       *mp++ = vb[2];
  58.       mp++;
  59.       tb[1] = t + dt;
  60.       vb[1] = y + dy;
  61.       v = N * N - x * x - (y + dy) * (y + dy);
  62.       if (v < 0.0)
  63.         v = 0.0;
  64.       vb[2] = sqrt(v) + B;
  65.       if (vb[2] < 0.)
  66.         vb[2] = 0.0;
  67.       *mp++ = tb[0];
  68.       *mp++ = tb[1];
  69.       mp += 2;
  70.       *mp++ = vb[0];
  71.       *mp++ = vb[1];
  72.       *mp++ = vb[2];
  73.       mp++;
  74.       x += dx;
  75.       s += ds;
  76.     }
  77.     y += dy;
  78.     t += dt;
  79.   }
  80. }
  81.  
  82. void
  83. drawmesh(int nx, int ny)
  84. {
  85.   float *mp = Ml;
  86.   int i, j;
  87.  
  88.   glColor4f(1, 1, 1, 1);
  89.   for (i = ny + 1; i; i--) {
  90.     glBegin(GL_TRIANGLE_STRIP);
  91.     for (j = nx + 1; j; j--) {
  92.       glTexCoord2fv(mp);
  93.       glVertex3fv(mp + 4);
  94.       glTexCoord2fv(mp + 8);
  95.       glVertex3fv(mp + 12);
  96.       mp += 16;
  97.     }
  98.     glEnd();
  99.   }
  100. }
  101.  
  102. void
  103. move(void)
  104. {
  105.   if (N > 2.1 || N < 1.5)
  106.     dir = -dir;
  107.   N += incr * dir;
  108.   mesh1(-1.5, 1.5, -1.5, 1.5, 0.0, 1.0, 0.0, 1.0, 0.0, MAXMESH, MAXMESH);
  109.   glutPostRedisplay();
  110. }
  111.  
  112. void
  113. alphaup(void)
  114. {
  115.   incr += .01;
  116.   if (incr > .1)
  117.     incr = .1;
  118.   glutPostRedisplay();
  119. }
  120.  
  121. void
  122. alphadown(void)
  123. {
  124.   incr -= .01;
  125.   if (incr < 0)
  126.     incr = 0;
  127.   glutPostRedisplay();
  128. }
  129.  
  130. void
  131. wire(void)
  132. {
  133.   static int wire_mode;
  134.   if (wire_mode ^= 1)
  135.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  136.   else
  137.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  138. }
  139.  
  140. void
  141. help(void)
  142. {
  143.   printf("'h'   - help\n");
  144.   printf("'w'   - wire frame\n");
  145.   printf("UP      - faster\n");
  146.   printf("DOWN  - slower\n");
  147. }
  148.  
  149. void
  150. init(char *filename)
  151. {
  152.   if (filename) {
  153.     image = read_texture(filename, &width, &height, &components);
  154.     if (image == NULL) {
  155.       fprintf(stderr, "Error: Can't load image file \"%s\".\n",
  156.         filename);
  157.       exit(1);
  158.     } else {
  159.       printf("%d x %d image loaded\n", width, height);
  160.     }
  161.     if (components < 3 || components > 4) {
  162.       printf("must be RGB or RGBA image\n");
  163.       exit(1);
  164.     }
  165.   } else {
  166.     int i, j;
  167.     components = 4;
  168.     width = height = 512;
  169.     image = (unsigned *) malloc(width * height * sizeof(unsigned));
  170.     for (j = 0; j < height; j++)
  171.       for (i = 0; i < width; i++) {
  172.         if (i & 64)
  173.           image[i + j * width] = 0xff;
  174.         else
  175.           image[i + j * width] = 0xff00;
  176.         if (j & 64)
  177.           image[i + j * width] |= 0xff0000;
  178.       }
  179.  
  180.   }
  181.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  182.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  183.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  184.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  185.   glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  186.     height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  187.     image);
  188.   glEnable(GL_TEXTURE_2D);
  189.   glMatrixMode(GL_TEXTURE);
  190.   glLoadIdentity();
  191.   glMatrixMode(GL_PROJECTION);
  192.   glLoadIdentity();
  193.   gluPerspective(90., 1., .1, 10.);
  194.   glMatrixMode(GL_MODELVIEW);
  195.   glLoadIdentity();
  196.   glTranslatef(0., 0., -1.5);
  197.   glClearColor(.25, .25, .25, 0.);
  198.  
  199. }
  200.  
  201. void
  202. display(void)
  203. {
  204.   glClear(GL_COLOR_BUFFER_BIT);
  205.   drawmesh(MAXMESH, MAXMESH);
  206.   glutSwapBuffers();
  207. }
  208.  
  209. void
  210. reshape(int w, int h)
  211. {
  212.   glViewport(0, 0, w, h);
  213. }
  214.  
  215. /* ARGSUSED1 */
  216. void
  217. key(unsigned char key, int x, int y)
  218. {
  219.   switch (key) {
  220.   case '\033':
  221.     exit(0);
  222.     break;
  223.   case 'h':
  224.     help();
  225.     break;
  226.   case 'w':
  227.     wire();
  228.     break;
  229.   }
  230. }
  231.  
  232. /* ARGSUSED1 */
  233. void
  234. special(int key, int x, int y)
  235. {
  236.   switch (key) {
  237.   case GLUT_KEY_UP:
  238.     alphaup();
  239.     break;
  240.   case GLUT_KEY_DOWN:
  241.     alphadown();
  242.     break;
  243.   }
  244. }
  245.  
  246. void
  247. visible(int vis)
  248. {
  249.   if (vis == GLUT_VISIBLE)
  250.     glutIdleFunc(move);
  251.   else
  252.     glutIdleFunc(NULL);
  253. }
  254.  
  255. void
  256. menu(int value)
  257. {
  258.   if(value < 0)
  259.     special(-value, 0, 0);
  260.   else
  261.     key((unsigned char) value, 0, 0);
  262. }
  263.  
  264. int
  265. main(int argc, char **argv)
  266. {
  267.   glutInit(&argc, argv);
  268.   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  269.   (void) glutCreateWindow("warp");
  270.   init(argv[1]);
  271.   glutKeyboardFunc(key);
  272.   glutSpecialFunc(special);
  273.   glutDisplayFunc(display);
  274.   glutReshapeFunc(reshape);
  275.   glutVisibilityFunc(visible);
  276.   glutCreateMenu(menu);
  277.   glutAddMenuEntry("Toggle wireframe", 'w');
  278.   glutAddMenuEntry("Quicken warping", -GLUT_KEY_UP);
  279.   glutAddMenuEntry("Slow warping", -GLUT_KEY_DOWN);
  280.   glutAddMenuEntry("Quit", '\033');
  281.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  282.   glutMainLoop();
  283.   return 0;             /* ANSI C requires main to return int. */
  284. }
  285.